﻿@namespace AntDesign
@inherits ColumnBase
@using AntDesign.Core.Helpers
@using AntDesign.Filters
@using AntDesign.TableModels
@using Microsoft.AspNetCore.Components.Rendering;
@using System.Linq.Expressions;
@typeparam TData

@if (IsInitialize)
{
    return;
}
else if (Hidden)
{
    return;
}
else if (IsPlaceholder)
{
    <td style="padding: 0px; border: 0px; height: 0px;"></td>
}
else if (IsMeasure)
{
    <td style="padding: 0px; border: 0px; height: 0px;"><div style="height: 0px; overflow: hidden;">&nbsp;</div></td>
}
else if (IsColGroup)
{
    @if (AppendExpandColumn)
    {
        <col class="ant-table-expand-icon-col">
    }

    if (Width != null)
    {
        <col style="width: @((CssSizeLength)Width); min-width: @((CssSizeLength)Width);">
    }
    else
    {
        <col />
    }
}
else if (IsHeader && HeaderColSpan != 0)
{

    @if (AppendExpandColumn)
    {
        <th class="ant-table-cell ant-table-row-expand-icon-cell"></th>
    }

    var headerCellAttributes = OnHeaderCell?.Invoke();
    <CascadingValue Name="IsHeader" Value="false" IsFixed>
     <th class="@ClassMapper.Class" style="@FixedStyle @HeaderStyle" colspan="@(HeaderColSpan > 1 ? HeaderColSpan : false)" rowspan="@(RowSpan > 1 ? RowSpan : false)" title="@(Ellipsis ? Title : false)" @attributes="headerCellAttributes">
         @if (IsFiexedEllipsis)
            {
                <span class="ant-table-cell-content">
                    @HeaderCellContent()
                </span>
            }
            else
            {
                @HeaderCellContent()
            }
        </th>
    </CascadingValue>
}
else if (IsBody && RowSpan != 0 && ColSpan != 0)
{
    @if (AppendExpandColumn)
    {
        <td class="ant-table-cell ant-table-row-expand-icon-cell">
            @if (Table.RowExpandable(RowData) && (!Table.TreeMode || !DataItem.HasChildren))
            {
                <button type="button" @onclick="ToggleTreeNode" @onclick:stopPropagation
                        class="ant-table-row-expand-icon @(RowData.Expanded ? "ant-table-row-expand-icon-expanded" : "ant-table-row-expand-icon-collapsed")"
                        aria-label="@(RowData.Expanded ? Table.Locale.Collapse : Table.Locale.Expand)"></button>
            }
        </td>
    }

    <CascadingValue Name="IsBody" Value="false" IsFixed>
     @{
            var cellAttributes = new Dictionary<string, object>();
            var cellData = new CellData<TData>(RowData, default, Format);

            var title = Context.HeaderColumns.LastOrDefault(x => x.ColIndex <= ColIndex && x.ColIndex + x.HeaderColSpan > ColIndex)?.Title;
            var fieldText = string.Empty;

            @if (!RowData.IsGrouping)
            {
                cellData = new CellData<TData>(RowData, Field, Format);
                cellAttributes = OnCell?.Invoke(cellData);
                fieldText = !string.IsNullOrWhiteSpace(Format) ? Formatter<TData>.Format(Field, Format) : Field is string text ? text : string.Empty;
            }
        }

        <td class="@ClassMapper.Class" style="@FixedStyle @Style" rowspan="@RowSpan" colspan="@ColSpan" title="@(Ellipsis ? fieldText : false)" data-label="@title" @attributes="cellAttributes">
            @if (ColIndex == Table.TreeExpandIconColumnIndex && (Table.TreeMode || RowData.IsGrouping))
            {
                <span class="ant-table-row-indent indent-level-@RowData.Level" style="padding-left: @((CssSizeLength)(RowData.Level * Table.IndentSize));"></span>
                @if (DataItem.HasChildren)
                {
                    <button type="button" @onclick="ToggleTreeNode" @onclick:stopPropagation class="ant-table-row-expand-icon @(RowData?.Expanded == true ? "ant-table-row-expand-icon-expanded" : "ant-table-row-expand-icon-collapsed")" aria-label="@(RowData?.Expanded == true ? Table.Locale.Collapse : Table.Locale.Expand)"></button>
                }
                else
                {
                    <button type="button" class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced" aria-label="@Table.Locale.Expand"></button>
                }
            }

            @if (RowData.IsGrouping && ColIndex == Table.TreeExpandIconColumnIndex)
            {
                @RowData.Key
            }
            else if (IsFiexedEllipsis)
            {
                <span class="ant-table-cell-content">
                    @CellContent(cellData)
                </span>
            }
            else
            {
                @CellContent(cellData)
            }
        </td>
    </CascadingValue>
}

@code
{
    RenderFragment ColumnTitle()
    {
        return @<span class="ant-table-column-title">
            @if (TitleTemplate != null)
            {
                @TitleTemplate
            }
            else
            {
                @Title
            }
        </span>
        ;
    }

    RenderFragment CellContent(CellData<TData> cellData)
    {
        if (CellRender != null)
        {
            return CellRender(cellData);
        }
        else if (ChildContent != null)
        {
            return ChildContent;
        }
        else
        {
            return builder => builder.AddContent(1, cellData.FormattedValue);
        }
    }

    RenderFragment HeaderCellContent()
    {
        if (Sortable || (_filterable && _filters?.Any() == true))
        {
            return FilterToolTipSorter();
        }
        else
        {
            return ColumnTitle();
        }
    }

    RenderFragment SortHeader()
    {
        bool hasDescendingSorter = SortDirection.Descending.IsIn(SortDirections);
        bool hasAscendingSorter = SortDirection.Ascending.IsIn(SortDirections);

        return builder =>
        {
            builder.AddContent(1, ColumnTitle());

            builder.AddContent(2,
                @<span class="ant-table-column-sorter@(hasDescendingSorter && hasAscendingSorter ? " ant-table-column-sorter-full" : "")">
                    <span class="ant-table-column-sorter-inner">
                        @if (hasAscendingSorter)
                        {
                            <Icon Type="caret-up" Class=@($"ant-table-column-sorter-up{(_sortDirection == SortDirection.Ascending ? " active" : "")}") />
                        }
                        @if (hasDescendingSorter)
                        {
                            <Icon Type="caret-down" Class=@($"ant-table-column-sorter-down{(_sortDirection == SortDirection.Descending ? " active" : "")}") />
                        }
                    </span>
                </span>
            );
        };
    }

    RenderFragment ToolTipSorter()
    {
        if (ShowSorterTooltip)
        {
            return@<Tooltip Title="@SorterTooltip">
                <Unbound>
                    <div class="ant-table-column-sorters" @ref="context.Current" @onclick="HandleSort">
                        @SortHeader()
                    </div>
                </Unbound>
            </Tooltip>
        ;
        }
        else
        {
            return@<div class="ant-table-column-sorters" @onclick="HandleSort">
                @SortHeader()
            </div>
        ;
        }
    }

    RenderFragment FilterToolTipSorter()
    {
        @if (_filterable)
        {
            return@<div class="ant-table-filter-column">
                @if (Sortable)
                {
                    @ToolTipSorter()
                }
                else
                {
                    @ColumnTitle()
                }

                <Dropdown Trigger="new[] { Trigger.Click }" Visible="_filterOpened" Placement="Placement.BottomRight" OnMaskClick="() => { if (_filterOpened) FilterConfirm(); }" OnVisibleChange="FilterDropdownOnVisibleChange">
                    <Unbound>
                        <span @ref="context.Current" role="button" tabindex="-1" class="ant-dropdown-trigger ant-table-filter-trigger@((_filterOpened ? " ant-dropdown-open" : "") + (_hasFilterSelected ? " active" : ""))"
                              @onclick="() => { if (_filterOpened) FilterConfirm(); else _filterOpened = true; }">
                            <Icon Type="filter" Theme="fill" />
                        </span>
                    </Unbound>
                    <Overlay>
                        <div class="ant-table-filter-dropdown">
                            @if (FilterDropdown != null)
                            {
                                @FilterDropdown
                            }
                            else
                            {
                                @_renderDefaultFilterDropdown
                            }
                        </div>
                    </Overlay>
                </Dropdown>
            </div>
    ;
        }
        else
        {
            return builder => builder.AddContent(1, ToolTipSorter());
        }
    }


    private void RenderDefaultFilterDropdown(RenderTreeBuilder __builder)
    {
        @if (_filters.Any() == true && _columnFilterType == TableFilterType.List)
        {
            <Menu AutoCloseDropdown="false" SelectedKeys="_selectedFilterValues">
                @foreach (var filter in _filters)
                {
                    <MenuItem Key="@filter.Value?.ToString()" OnClick="() => FilterSelected(filter)">
                        @if (FilterMultiple)
                        {
                            <Checkbox Value="filter.Selected" ValueChanged="value => FilterSelected(filter)">@filter.Text</Checkbox>
                        }
                        else
                        {
                            <Radio TValue="bool" Checked="filter.Selected" CheckedChanged="value => FilterSelected(filter)">@filter.Text</Radio>
                        }
                    </MenuItem>
                }
            </Menu>
        }
        else
        {
            <div id="@("popup-container-for-" + Id)" style="position:relative!important"></div>
            int index = 0;
            int filterCount = _filters.Count();
            @foreach (TableFilter filter in _filters)
            {
                var noInput = filter.FilterCompareOperator is TableFilterCompareOperator.IsNull or TableFilterCompareOperator.IsNotNull;
                <div @key="filter" style="padding:10px;min-width:150px;@(index > 0 ? "border-top:1px solid #f0f0f0" : "")">
                    @if (index > 0)
                    {
                        <div>
                            <Space Style="margin-bottom:10px">
                                <SpaceItem>
                                    <Select Value="filter.FilterCondition" TItemValue="TableFilterCondition" TItem="TableFilterCondition" ValueChanged="value => SetFilterCondition(filter,value)" PopupContainerSelector="@("#popup-container-for-" + Id)" BoundaryAdjustMode="@TriggerBoundaryAdjustMode.None">
                                        <SelectOptions>
                                            <SelectOption TItem="TableFilterCondition" TItemValue="TableFilterCondition" Value="@TableFilterCondition.And" Label="@Table?.Locale.FilterOptions.And"></SelectOption>
                                            <SelectOption TItem="TableFilterCondition" TItemValue="TableFilterCondition" Value="@TableFilterCondition.Or" Label="@Table?.Locale.FilterOptions.Or"></SelectOption>
                                        </SelectOptions>
                                    </Select>
                                </SpaceItem>
                            </Space>
                        </div>
                    }
                    <Space Style="width:100%;">
                        <SpaceItem Style="flex:auto">
                            <Select Value="filter.FilterCompareOperator" TItemValue="TableFilterCompareOperator" TItem="TableFilterCompareOperator" Style="width: 100%; overflow: visible" ValueChanged="value => SetFilterCompareOperator(filter,value)" PopupContainerSelector="@("#popup-container-for-" + Id)" BoundaryAdjustMode="@TriggerBoundaryAdjustMode.None" DropdownMatchSelectWidth="false">
                                <SelectOptions>
                                    @foreach (TableFilterCompareOperator compareOperator in _fieldFilterType.SupportedCompareOperators)
                                    {
                                        if (compareOperator is TableFilterCompareOperator.IsNull or TableFilterCompareOperator.IsNotNull
                                        && !(THelper.IsTypeNullable<TData>() || _columnDataType == typeof(string)))
                                            continue;

                                        <SelectOption TItem="TableFilterCompareOperator" TItemValue="TableFilterCompareOperator"
                                                      Value="@compareOperator" Label="@Table?.Locale.FilterOptions.Operator(compareOperator)" />
                                    }
                                </SelectOptions>
                            </Select>
                        </SpaceItem>
                        @if (!noInput)
                        {
                            <SpaceItem>
                                @_fieldFilterType.FilterInput(new TableFilterInputRenderOptions(filter, "#popup-container-for-" + Id, Format, Expression.Field(Expression.Constant(this), nameof(_filterInputRef))))
                            </SpaceItem>
                        }
                        @if (filterCount > 1)
                        {
                            <SpaceItem>
                                <Button Size="small" Icon="close" Type="primary" OnClick="()=> RemoveFilter(filter)">
                                </Button>
                            </SpaceItem>
                        }
                    </Space>
                </div>
                index++;
            }
        }
        <div class="ant-table-filter-dropdown-btns">
            <Button Size="small" Type="link" OnClick="ResetFilters">
                @Table?.Locale.FilterReset
            </Button>
            @if (_columnFilterType == TableFilterType.FieldType)
            {
                <Button Size="small" Icon="plus" Type="primary" OnClick="AddFilter">
                </Button>
            }
            <Button Size="small" Type="primary" OnClick="() => FilterConfirm()">
                @Table?.Locale.FilterConfirm
            </Button>
        </div>
    }
}